package controllers

import (
	"admin-glm-go/internal/models"
	"admin-glm-go/internal/response"
	"admin-glm-go/internal/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// AdminListRequest 管理员列表请求参数
type AdminListRequest struct {
	Page     int    `form:"page"`
	PageSize int    `form:"pageSize"`
	Username string `form:"username"`
	Nickname string `form:"nickname"`
	Status   int    `form:"status"`
}

// AddAdminRequest 添加管理员请求参数
type AddAdminRequest struct {
	Username string   `json:"username" binding:"required"`
	Password string   `json:"password" binding:"required"`
	Nickname string   `json:"nickname"`
	Avatar   string   `json:"avatar"`
	Email    string   `json:"email"`
	Phone    string   `json:"phone"`
	Status   int      `json:"status"`
	RoleIds  []uint64 `json:"roleIds"`
}

// UpdateAdminRequest 更新管理员请求参数
type UpdateAdminRequest struct {
	ID       uint64   `json:"id" binding:"required"`
	Username string   `json:"username" binding:"required"`
	Nickname string   `json:"nickname"`
	Avatar   string   `json:"avatar"`
	Email    string   `json:"email"`
	Phone    string   `json:"phone"`
	Status   int      `json:"status"`
	RoleIds  []uint64 `json:"roleIds"`
}

// ResetPasswordRequest 重置密码请求参数
type ResetPasswordRequest struct {
	ID       uint64 `json:"id" binding:"required"`
	Password string `json:"password" binding:"required"`
}

// AdminController 管理员控制器
type AdminController struct {
	db *gorm.DB
}

// NewAdminController 创建管理员控制器
func NewAdminController(db *gorm.DB) *AdminController {
	return &AdminController{db: db}
}

// GetAdminList 获取管理员列表
// @Summary 获取管理员列表
// @Description 获取管理员列表
// @Tags 管理员管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param page query int false "页码"
// @Param pageSize query int false "每页数量"
// @Param username query string false "用户名"
// @Param nickname query string false "昵称"
// @Param status query int false "状态"
// @Success 200 {object} response.Response
// @Router /admin/list [get]
func (ctrl *AdminController) GetAdminList(c *gin.Context) {
	var req AdminListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}

	// 构建查询条件
	query := ctrl.db.Model(&models.Admin{})
	if req.Username != "" {
		query = query.Where("username LIKE ?", "%"+req.Username+"%")
	}
	if req.Nickname != "" {
		query = query.Where("nickname LIKE ?", "%"+req.Nickname+"%")
	}
	if req.Status != 0 {
		query = query.Where("status = ?", req.Status)
	}

	// 获取总数
	var total int64
	query.Count(&total)

	// 分页查询
	var admins []models.Admin
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("Roles").Offset(offset).Limit(req.PageSize).Order("id DESC").Find(&admins).Error
	if err != nil {
		response.ServerError(c)
		return
	}

	// 构建响应数据
	var records []gin.H
	for _, admin := range admins {
		var roleIds []uint64
		for _, role := range admin.Roles {
			roleIds = append(roleIds, role.ID)
		}

		record := gin.H{
			"id":         admin.ID,
			"username":   admin.Username,
			"nickname":   admin.Nickname,
			"avatar":     admin.Avatar,
			"email":      admin.Email,
			"phone":      admin.Phone,
			"status":     admin.Status,
			"roles":      roleIds,
			"createTime": admin.CreateTime.Format("2006-01-02 15:04:05"),
			"updateTime": admin.UpdateTime.Format("2006-01-02 15:04:05"),
		}
		records = append(records, record)
	}

	response.PageSuccess(c, total, records, req.Page, req.PageSize)
}

// AddAdmin 添加管理员
// @Summary 添加管理员
// @Description 添加管理员
// @Tags 管理员管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param body body AddAdminRequest true "管理员信息"
// @Success 200 {object} response.Response
// @Router /admin/add [post]
func (ctrl *AdminController) AddAdmin(c *gin.Context) {
	var req AddAdminRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 检查用户名是否已存在
	var count int64
	if err := ctrl.db.Model(&models.Admin{}).Where("username = ?", req.Username).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "用户名已存在")
		return
	}

	// 加密密码
	hashedPassword, err := utils.HashPassword(req.Password)
	if err != nil {
		response.ServerError(c)
		return
	}

	// 创建管理员
	admin := models.Admin{
		Username: req.Username,
		Password: hashedPassword,
		Nickname: req.Nickname,
		Avatar:   req.Avatar,
		Email:    req.Email,
		Phone:    req.Phone,
		Status:   req.Status,
	}

	// 开启事务
	tx := ctrl.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存管理员
	if err := tx.Create(&admin).Error; err != nil {
		tx.Rollback()
		response.ServerError(c)
		return
	}

	// 分配角色
	if len(req.RoleIds) > 0 {
		var roles []models.Role
		if err := tx.Where("id IN ?", req.RoleIds).Find(&roles).Error; err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}

		if err := tx.Model(&admin).Association("Roles").Replace(roles); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// UpdateAdmin 更新管理员
// @Summary 更新管理员
// @Description 更新管理员
// @Tags 管理员管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param body body UpdateAdminRequest true "管理员信息"
// @Success 200 {object} response.Response
// @Router /admin/update [put]
func (ctrl *AdminController) UpdateAdmin(c *gin.Context) {
	var req UpdateAdminRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 查询管理员
	var admin models.Admin
	if err := ctrl.db.First(&admin, req.ID).Error; err != nil {
		response.NotFound(c)
		return
	}

	// 检查用户名是否已存在（排除自己）
	var count int64
	if err := ctrl.db.Model(&models.Admin{}).Where("username = ? AND id != ?", req.Username, req.ID).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "用户名已存在")
		return
	}

	// 更新管理员信息
	admin.Username = req.Username
	admin.Nickname = req.Nickname
	admin.Avatar = req.Avatar
	admin.Email = req.Email
	admin.Phone = req.Phone
	admin.Status = req.Status

	// 开启事务
	tx := ctrl.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存管理员
	if err := tx.Save(&admin).Error; err != nil {
		tx.Rollback()
		response.ServerError(c)
		return
	}

	// 更新角色
	if len(req.RoleIds) > 0 {
		var roles []models.Role
		if err := tx.Where("id IN ?", req.RoleIds).Find(&roles).Error; err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}

		if err := tx.Model(&admin).Association("Roles").Replace(roles); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	} else {
		// 清空角色
		if err := tx.Model(&admin).Association("Roles").Clear(); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// DeleteAdmin 删除管理员
// @Summary 删除管理员
// @Description 删除管理员
// @Tags 管理员管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "管理员ID"
// @Success 200 {object} response.Response
// @Router /admin/delete/{id} [delete]
func (ctrl *AdminController) DeleteAdmin(c *gin.Context) {
	id := utils.StringToUint(c.Param("id"))
	if id == 0 {
		response.ParamError(c)
		return
	}

	// 查询管理员
	var admin models.Admin
	if err := ctrl.db.First(&admin, id).Error; err != nil {
		response.NotFound(c)
		return
	}

	// 删除管理员
	if err := ctrl.db.Delete(&admin).Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// ResetPassword 重置管理员密码
// @Summary 重置管理员密码
// @Description 重置管理员密码
// @Tags 管理员管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param body body ResetPasswordRequest true "重置密码参数"
// @Success 200 {object} response.Response
// @Router /admin/reset-password [put]
func (ctrl *AdminController) ResetPassword(c *gin.Context) {
	var req ResetPasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 查询管理员
	var admin models.Admin
	if err := ctrl.db.First(&admin, req.ID).Error; err != nil {
		response.NotFound(c)
		return
	}

	// 加密密码
	hashedPassword, err := utils.HashPassword(req.Password)
	if err != nil {
		response.ServerError(c)
		return
	}

	// 更新密码
	admin.Password = hashedPassword
	if err := ctrl.db.Save(&admin).Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}